package hk.com.fgoproduction.getdroplets.Lib.Common.AdaptiveStorage

import android.os.Build
import android.os.Environment
import android.text.TextUtils
import java.io.File
import java.util.*
import java.util.regex.Pattern

object GetSdcardList {

    private val DIR_SEPORATOR = Pattern.compile("/")

    /**
     * Raturns all available SD-Cards in the system (include emulated)
     * * * Warning: Hack! Based on Android source code of version 4.3 (API 18)
     * * Because there is no standart way to get it.
     * * TODO: Test on future Android versions 4.4+
     * * * @return paths to all available SD-Cards in the system (include emulated)
     */
    // Final set of paths
    // Primary physical SD-CARD (not emulated)
    // All Secondary SD-CARDs (all exclude primary) separated by ":"
    // Primary emulated SD-CARD
    // Device has physical external storage; use plain paths.
    // EXTERNAL_STORAGE undefined; falling back to default.
    // Device has emulated storage; external storage paths should have
    // userId burned into them.
    // /storage/emulated/0[1,2,...]
    // Add all secondary storages
    // All Secondary SD-CARDs splited into array
    val storageDirectories: Array<String>
        get() {
            val rv = HashSet<String>()
            val rawExternalStorage = System.getenv("EXTERNAL_STORAGE")
            val rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE")
            val rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET")

            if (TextUtils.isEmpty(rawEmulatedStorageTarget)) {
                if (TextUtils.isEmpty(rawExternalStorage)) {
                    rv.add("/storage/sdcard0")
                } else {
                    rv.add(rawExternalStorage)
                }
            } else {
                val rawUserId: String
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
                    rawUserId = ""
                } else {
                    val path = Environment.getExternalStorageDirectory().absolutePath
                    val folders = DIR_SEPORATOR.split(path)
                    val lastFolder = folders[folders.size - 1]
                    var isDigit = false
                    try {
                        Integer.valueOf(lastFolder)
                        isDigit = true
                    } catch (ignored: NumberFormatException) {

                    }

                    rawUserId = if (isDigit) lastFolder else ""
                }
                if (TextUtils.isEmpty(rawUserId)) {
                    rv.add(rawEmulatedStorageTarget)
                } else {
                    rv.add(rawEmulatedStorageTarget + File.separator + rawUserId)
                }
            }
            if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) {
                val rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                Collections.addAll(rv, *rawSecondaryStorages)
            }
            return rv.toTypedArray()
        }

    // parse output
    val externalMounts: HashSet<String>
        get() {
            val out = HashSet<String>()
            val reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*"
            var s = ""
            try {
                val process = ProcessBuilder().command("mount").redirectErrorStream(true).start()
                process.waitFor()
                val `is` = process.inputStream
                val buffer = ByteArray(1024)
                while (`is`.read(buffer) != -1) {
                    s += String(buffer)
                }
                `is`.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }

            val lines = s.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
            for (line in lines) {
                if (!line.toLowerCase(Locale.US).contains("asec")) {
                    if (line.matches(reg.toRegex())) {
                        val parts = line.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                        for (part in parts) {
                            if (part.startsWith("/"))
                                if (!part.toLowerCase(Locale.US).contains("vold"))
                                    out.add(part)
                        }
                    }
                }
            }
            return out
        }

}


